﻿using LearningMVC.GenericRepository;
using LearningMVC.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/*
 De acordo com Martin Fowler, o padrão de unidade de trabalho 
 * "mantém uma lista de objetos afetados por uma transação e coordena a escrita de mudanças e trata possíveis problemas de concorrência".
O padrão de unidade de trabalho não é necessariamente algo que você vai implementar explicitamente. 
 * A interface ITransaction em NHibernate, a classe DataContext no LINQ to SQL, e a classe ObjectContext no Entity Framework, 
 * são exemplos de uma Unidade de Trabalho.
Porém existem várias razões para implementar sua própria unidade de trabalho como efetuar logs, 
 * tracing, gerenciar as transações, promover testabilidade em seu sistema, entre outras.
Leia mais em: Unit of work - O padrão de unidade de trabalho 
 * (.NET) http://www.devmedia.com.br/unit-of-work-o-padrao-de-unidade-de-trabalho-net/25811#ixzz2e7oRaoRj
 */
namespace LearningMVC.UnitOfWork
{
    public class UnitOfWork : IDisposable
    {
        private MVCDBContext context = new MVCDBContext();

        private GenericRepository<User> userRepository;
		private GenericRepository<Product> productRepository;

        public GenericRepository<User> UserRepository
        {
            get
            {
                if (this.userRepository == null)
                {
                    this.userRepository = new GenericRepository<User>(context);
                }
                return userRepository;
            }
        }

		public GenericRepository<Product> ProductRepository
		{
			get
			{
				if (this.productRepository == null)
				{
					this.productRepository = new GenericRepository<Product>(context);
				}
				return productRepository;
			}
		}

        public void Save()
        {
            context.SaveChanges();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }
}